library(tidyverse)
library(ggplot2)  
library(plotly)
library(kableExtra)
library(shiny)
library(tidyr)
library(dplyr)
levels_df <- read.csv("./levels-cleaned.csv")
drop <- c("X", "timestamp")
levels_df <- levels_df[,!(names(levels_df) %in% drop)]
levels_df
pres <- levels_df %>%
  select(company, totalyearlycompensation, 
         title, yearsofexperience, location, gender, lat, long, year)
  
head(pres) %>%
  kbl() %>%
  kable_styling() %>% 
  save_kable("combined_tables.png")
Sys.setenv("MAPBOX_TOKEN" = "pk.eyJ1IjoidGltb3RoeW5ndXllIiwiYSI6ImNrbW8wZmR0OTF6cnoycHQ0ZXFydTBwY3oifQ.LumCjldRn9X9jX70p1BA-w")

Let’s take a look at highest total compensation by entry level candidates

new_entry <- levels_df %>% filter(yearsofexperience <= 1.5)
new_entry
new_entry <- new_entry %>% 
                drop_na(basesalary)  %>%
                drop_na(title) %>%
                drop_na(stockgrantvalue) %>%
                drop_na(bonus)
'
new_entry_tc <- aggregate(new_entry$totalyearlycompensation, 
                          by=list(location=new_entry$location), 
                          FUN=mean, na.action = na.omit)
names(new_entry_tc)[names(new_entry_tc) == "x"] <- "tc"
new_entry_tc
'
[1] "\nnew_entry_tc <- aggregate(new_entry$totalyearlycompensation, \n                          by=list(location=new_entry$location), \n                          FUN=mean, na.action = na.omit)\nnames(new_entry_tc)[names(new_entry_tc) == \"x\"] <- \"tc\"\nnew_entry_tc\n"
new_entry_tc <- aggregate(list(new_entry$totalyearlycompensation,
                               new_entry$basesalary,
                               new_entry$stockgrantvalue,
                               new_entry$bonus), 
                          by=list(location=new_entry$location), 
                          FUN=mean, na.action = na.omit)
names(new_entry_tc)[2] <- "tc"
names(new_entry_tc)[3] <- "basesalary"
names(new_entry_tc)[4] <- "stockgrantvalue"
names(new_entry_tc)[5] <- "bonus"
new_entry_tc
location_df <- new_entry %>% 
  distinct(location, .keep_all = TRUE) %>%
  select(location, zip, lat, long, city, state)
location_df
new_entry_tc <- new_entry_tc %>%
  left_join(location_df)
Joining, by = "location"
new_entry_tc
fig <- new_entry_tc
fig <- fig %>%
  plot_mapbox() %>%
  add_markers(x = ~long,
              y = ~lat,
              color = ~state,
              size = ~tc*100,
              text = ~paste0(location, "<br>",
                 "<b>Mean Yearly Compensation:</b> $", tc, "<br>",
                 "<b>Mean Salary Base:</b> $", basesalary, "<br>",
                 "<b>Mean stocks grants:</b> $", stockgrantvalue, "<br>",
                 "<b>Mean bonus:</b> $", bonus, "<br>")) %>%
  layout(
    mapbox = list(
      style = 'open-street-map',
      center = list(lon = -97, lat = 38),
      zoom = 2.5)) 

fig
Ignoring 9 observations`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Ignoring 9 observations`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.`line.width` does not currently support multiple values.n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
 levels_df %>% 
        filter(yearsofexperience >= 1.5)
ui <-
  fluidPage(
    # App title
    titlePanel("Years of Experience, Location & Total Compensation"),
    
    # sidebar layout with input and output definitions
    sidebarLayout(
      # Sidebar panel for inputs
      sidebarPanel(
        sliderInput("yoe",
                    "Years of experience",
                    min = min(levels_df$yearsofexperience),
                    max = max(levels_df$yearsofexperience),
                    value = c(min(levels_df$yearsofexperience), 
                              max(levels_df$yearsofexperience)),
                    step = 1,
                    sep = "")
      ),
      
      # Main panel for displaying outputs
      mainPanel(
        plotlyOutput(outputId = "tc_loc")
      )
    ))
server <- function(input, output) {
  output$tc_loc <-
    renderPlotly({
      prep <- levels_df %>% 
        filter(yearsofexperience >= input$yoe[1] & 
              yearsofexperience <= input$yoe[2]) 
        
        
      tc <- aggregate(prep$totalyearlycompensation, 
                          by=list(location=prep$location), 
                          FUN=mean, na.action = na.omit)
      names(tc)[names(tc) == "x"] <- "tc"
    
      location_df <- prep %>% 
        distinct(location, .keep_all = TRUE) %>%
        select(location, zip, lat, long, city, state)
      
      tc <- tc %>% left_join(location_df)
      
      fig <- tc
      fig %>%
        plot_mapbox() %>%
        add_markers(x = ~long,
                    y = ~lat,
                    color = ~state,
                    size = ~tc*100,
                    text = ~paste0(location, "<br>",
                       "<b>Total Yearly Compensation:</b> $", tc)) %>%
        layout(
          mapbox = list(
            style = 'open-street-map',
            center = list(lon = -97, lat = 38),
            zoom = 2.5)) 
          })
}

shinyApp(ui, server)

Listening on http://127.0.0.1:7419
NA

Looking at different roles in companies based on role

con <- factor(unique(levels_df[c("title")])$title)
con
 [1] Product Manager              Software Engineer            Software Engineering Manager
 [4] Data Scientist               Solution Architect           Technical Program Manager   
 [7] Product Designer             Marketing                    Business Analyst            
[10] Hardware Engineer            Sales                        Recruiter                   
[13] Mechanical Engineer          Management Consultant       
14 Levels: Business Analyst Data Scientist Hardware Engineer Management Consultant Marketing ... Technical Program Manager
new_entry <- new_entry %>% 
                drop_na(basesalary)  %>%
                drop_na(title) %>%
                drop_na(stockgrantvalue) %>%
                drop_na(bonus)

new_entry_tc <- aggregate(list(tc = new_entry$totalyearlycompensation,
                               basesalary = new_entry$basesalary,
                               stockgrantvalue = new_entry$stockgrantvalue,
                               bonus = new_entry$bonus), 
                          by=list( title=new_entry$title, state=new_entry$state), 
                          FUN=mean, na.action = na.omit)
#names(new_entry_tc)[2] <- "state"
#names(new_entry_tc)[3] <- "tc"
#names(new_entry_tc)[4] <- "basesalary"
#names(new_entry_tc)[5] <- "stockgrantvalue"
#names(new_entry_tc)[6] <- "bonus"

new_entry_tc
location_df <- new_entry %>% 
  distinct(state, .keep_all = TRUE) %>%
  select(state, lat, long) %>% na.omit()
# location_df <- na.omit(location_df)
location_df
new_entry_tc <- new_entry_tc %>%
  left_join(location_df)
Joining, by = "state"
new_entry_tc
new_entry_tc %>% 
  filter(state == "AR") %>%
  ggplot(aes(x = title, y = tc, fill = title)) +
  geom_text(aes(y = tc, label = tc, hjust=0), 
                  size = 3) +
        geom_bar(stat = "identity")+
        coord_flip()+
        labs(x = "", y = "")+
        ggtitle(paste("Hello"))+
        theme(legend.title = element_blank(), legend.position = "none")

LS0tDQp0aXRsZTogIkxldmVscyBUQyBBbmFseXNpcyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdncGxvdDIpICANCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KbGlicmFyeShzaGlueSkNCmxpYnJhcnkodGlkeXIpDQpsaWJyYXJ5KGRwbHlyKQ0KYGBgDQoNCmBgYHtyfQ0KbGV2ZWxzX2RmIDwtIHJlYWQuY3N2KCIuL2xldmVscy1jbGVhbmVkLmNzdiIpDQpkcm9wIDwtIGMoIlgiLCAidGltZXN0YW1wIikNCmxldmVsc19kZiA8LSBsZXZlbHNfZGZbLCEobmFtZXMobGV2ZWxzX2RmKSAlaW4lIGRyb3ApXQ0KbGV2ZWxzX2RmDQpgYGANCg0KYGBge3J9DQpwcmVzIDwtIGxldmVsc19kZiAlPiUNCiAgc2VsZWN0KGNvbXBhbnksIHRvdGFseWVhcmx5Y29tcGVuc2F0aW9uLCANCiAgICAgICAgIHRpdGxlLCB5ZWFyc29mZXhwZXJpZW5jZSwgbG9jYXRpb24sIGdlbmRlciwgbGF0LCBsb25nLCB5ZWFyKQ0KICANCmhlYWQocHJlcykgJT4lDQogIGtibCgpICU+JQ0KICBrYWJsZV9zdHlsaW5nKCkgJT4lIA0KICBzYXZlX2thYmxlKCJjb21iaW5lZF90YWJsZXMucG5nIikNCmBgYA0KDQpgYGB7cn0NClN5cy5zZXRlbnYoIk1BUEJPWF9UT0tFTiIgPSAicGsuZXlKMUlqb2lkR2x0YjNSb2VXNW5kWGxsSWl3aVlTSTZJbU5yYlc4d1ptUjBPVEY2Y25veWNIUTBaWEZ5ZFRCd1kzb2lmUS5MdW1DamxkUm45WDlqWDcwcDFCQS13IikNCmBgYA0KDQpMZXQncyB0YWtlIGEgbG9vayBhdCBoaWdoZXN0IHRvdGFsIGNvbXBlbnNhdGlvbiBieSBlbnRyeSBsZXZlbCBjYW5kaWRhdGVzDQoNCmBgYHtyfQ0KbmV3X2VudHJ5IDwtIGxldmVsc19kZiAlPiUgZmlsdGVyKHllYXJzb2ZleHBlcmllbmNlIDw9IDEuNSkNCm5ld19lbnRyeQ0KYGBgDQoNCmBgYHtyfQ0KbmV3X2VudHJ5IDwtIG5ld19lbnRyeSAlPiUgDQogICAgICAgICAgICAgICAgZHJvcF9uYShiYXNlc2FsYXJ5KSAgJT4lDQogICAgICAgICAgICAgICAgZHJvcF9uYSh0aXRsZSkgJT4lDQogICAgICAgICAgICAgICAgZHJvcF9uYShzdG9ja2dyYW50dmFsdWUpICU+JQ0KICAgICAgICAgICAgICAgIGRyb3BfbmEoYm9udXMpDQonDQpuZXdfZW50cnlfdGMgPC0gYWdncmVnYXRlKG5ld19lbnRyeSR0b3RhbHllYXJseWNvbXBlbnNhdGlvbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGJ5PWxpc3QobG9jYXRpb249bmV3X2VudHJ5JGxvY2F0aW9uKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIEZVTj1tZWFuLCBuYS5hY3Rpb24gPSBuYS5vbWl0KQ0KbmFtZXMobmV3X2VudHJ5X3RjKVtuYW1lcyhuZXdfZW50cnlfdGMpID09ICJ4Il0gPC0gInRjIg0KbmV3X2VudHJ5X3RjDQonDQpuZXdfZW50cnlfdGMgPC0gYWdncmVnYXRlKGxpc3QobmV3X2VudHJ5JHRvdGFseWVhcmx5Y29tcGVuc2F0aW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld19lbnRyeSRiYXNlc2FsYXJ5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld19lbnRyeSRzdG9ja2dyYW50dmFsdWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X2VudHJ5JGJvbnVzKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGJ5PWxpc3QobG9jYXRpb249bmV3X2VudHJ5JGxvY2F0aW9uKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIEZVTj1tZWFuLCBuYS5hY3Rpb24gPSBuYS5vbWl0KQ0KbmFtZXMobmV3X2VudHJ5X3RjKVsyXSA8LSAidGMiDQpuYW1lcyhuZXdfZW50cnlfdGMpWzNdIDwtICJiYXNlc2FsYXJ5Ig0KbmFtZXMobmV3X2VudHJ5X3RjKVs0XSA8LSAic3RvY2tncmFudHZhbHVlIg0KbmFtZXMobmV3X2VudHJ5X3RjKVs1XSA8LSAiYm9udXMiDQpuZXdfZW50cnlfdGMNCmBgYA0KDQpgYGB7cn0NCmxvY2F0aW9uX2RmIDwtIG5ld19lbnRyeSAlPiUgDQogIGRpc3RpbmN0KGxvY2F0aW9uLCAua2VlcF9hbGwgPSBUUlVFKSAlPiUNCiAgc2VsZWN0KGxvY2F0aW9uLCB6aXAsIGxhdCwgbG9uZywgY2l0eSwgc3RhdGUpDQpsb2NhdGlvbl9kZg0KYGBgDQoNCmBgYHtyfQ0KbmV3X2VudHJ5X3RjIDwtIG5ld19lbnRyeV90YyAlPiUNCiAgbGVmdF9qb2luKGxvY2F0aW9uX2RmKQ0KbmV3X2VudHJ5X3RjDQpgYGANCg0KYGBge3J9DQpmaWcgPC0gbmV3X2VudHJ5X3RjDQpmaWcgPC0gZmlnICU+JQ0KICBwbG90X21hcGJveCgpICU+JQ0KICBhZGRfbWFya2Vycyh4ID0gfmxvbmcsDQogICAgICAgICAgICAgIHkgPSB+bGF0LA0KICAgICAgICAgICAgICBjb2xvciA9IH5zdGF0ZSwNCiAgICAgICAgICAgICAgc2l6ZSA9IH50YyoxMDAsDQogICAgICAgICAgICAgIHRleHQgPSB+cGFzdGUwKGxvY2F0aW9uLCAiPGJyPiIsDQogICAgICAgICAgICAgICAgICI8Yj5NZWFuIFllYXJseSBDb21wZW5zYXRpb246PC9iPiAkIiwgdGMsICI8YnI+IiwNCiAgICAgICAgICAgICAgICAgIjxiPk1lYW4gU2FsYXJ5IEJhc2U6PC9iPiAkIiwgYmFzZXNhbGFyeSwgIjxicj4iLA0KICAgICAgICAgICAgICAgICAiPGI+TWVhbiBzdG9ja3MgZ3JhbnRzOjwvYj4gJCIsIHN0b2NrZ3JhbnR2YWx1ZSwgIjxicj4iLA0KICAgICAgICAgICAgICAgICAiPGI+TWVhbiBib251czo8L2I+ICQiLCBib251cywgIjxicj4iKSkgJT4lDQogIGxheW91dCgNCiAgICBtYXBib3ggPSBsaXN0KA0KICAgICAgc3R5bGUgPSAnb3Blbi1zdHJlZXQtbWFwJywNCiAgICAgIGNlbnRlciA9IGxpc3QobG9uID0gLTk3LCBsYXQgPSAzOCksDQogICAgICB6b29tID0gMi41KSkgDQoNCmZpZw0KYGBgDQoNCmBgYHtyfQ0KIGxldmVsc19kZiAlPiUgDQogICAgICAgIGZpbHRlcih5ZWFyc29mZXhwZXJpZW5jZSA+PSAxLjUpDQpgYGANCg0KYGBge3J9DQp1aSA8LQ0KICBmbHVpZFBhZ2UoDQogICAgIyBBcHAgdGl0bGUNCiAgICB0aXRsZVBhbmVsKCJZZWFycyBvZiBFeHBlcmllbmNlLCBMb2NhdGlvbiAmIFRvdGFsIENvbXBlbnNhdGlvbiIpLA0KICAgIA0KICAgICMgc2lkZWJhciBsYXlvdXQgd2l0aCBpbnB1dCBhbmQgb3V0cHV0IGRlZmluaXRpb25zDQogICAgc2lkZWJhckxheW91dCgNCiAgICAgICMgU2lkZWJhciBwYW5lbCBmb3IgaW5wdXRzDQogICAgICBzaWRlYmFyUGFuZWwoDQogICAgICAgIHNsaWRlcklucHV0KCJ5b2UiLA0KICAgICAgICAgICAgICAgICAgICAiWWVhcnMgb2YgZXhwZXJpZW5jZSIsDQogICAgICAgICAgICAgICAgICAgIG1pbiA9IG1pbihsZXZlbHNfZGYkeWVhcnNvZmV4cGVyaWVuY2UpLA0KICAgICAgICAgICAgICAgICAgICBtYXggPSBtYXgobGV2ZWxzX2RmJHllYXJzb2ZleHBlcmllbmNlKSwNCiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBjKG1pbihsZXZlbHNfZGYkeWVhcnNvZmV4cGVyaWVuY2UpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChsZXZlbHNfZGYkeWVhcnNvZmV4cGVyaWVuY2UpKSwNCiAgICAgICAgICAgICAgICAgICAgc3RlcCA9IDEsDQogICAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKQ0KICAgICAgKSwNCiAgICAgIA0KICAgICAgIyBNYWluIHBhbmVsIGZvciBkaXNwbGF5aW5nIG91dHB1dHMNCiAgICAgIG1haW5QYW5lbCgNCiAgICAgICAgcGxvdGx5T3V0cHV0KG91dHB1dElkID0gInRjX2xvYyIpDQogICAgICApDQogICAgKSkNCnNlcnZlciA8LSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0KSB7DQogIG91dHB1dCR0Y19sb2MgPC0NCiAgICByZW5kZXJQbG90bHkoew0KICAgICAgcHJlcCA8LSBsZXZlbHNfZGYgJT4lIA0KICAgICAgICBmaWx0ZXIoeWVhcnNvZmV4cGVyaWVuY2UgPj0gaW5wdXQkeW9lWzFdICYgDQogICAgICAgICAgICAgIHllYXJzb2ZleHBlcmllbmNlIDw9IGlucHV0JHlvZVsyXSkgDQogICAgICAgIA0KICAgICAgICANCiAgICAgIHRjIDwtIGFnZ3JlZ2F0ZShwcmVwJHRvdGFseWVhcmx5Y29tcGVuc2F0aW9uLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgYnk9bGlzdChsb2NhdGlvbj1wcmVwJGxvY2F0aW9uKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIEZVTj1tZWFuLCBuYS5hY3Rpb24gPSBuYS5vbWl0KQ0KICAgICAgbmFtZXModGMpW25hbWVzKHRjKSA9PSAieCJdIDwtICJ0YyINCiAgICANCiAgICAgIGxvY2F0aW9uX2RmIDwtIHByZXAgJT4lIA0KICAgICAgICBkaXN0aW5jdChsb2NhdGlvbiwgLmtlZXBfYWxsID0gVFJVRSkgJT4lDQogICAgICAgIHNlbGVjdChsb2NhdGlvbiwgemlwLCBsYXQsIGxvbmcsIGNpdHksIHN0YXRlKQ0KICAgICAgDQogICAgICB0YyA8LSB0YyAlPiUgbGVmdF9qb2luKGxvY2F0aW9uX2RmKQ0KICAgICAgDQogICAgICBmaWcgPC0gdGMNCiAgICAgIGZpZyAlPiUNCiAgICAgICAgcGxvdF9tYXBib3goKSAlPiUNCiAgICAgICAgYWRkX21hcmtlcnMoeCA9IH5sb25nLA0KICAgICAgICAgICAgICAgICAgICB5ID0gfmxhdCwNCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB+c3RhdGUsDQogICAgICAgICAgICAgICAgICAgIHNpemUgPSB+dGMqMTAwLA0KICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gfnBhc3RlMChsb2NhdGlvbiwgIjxicj4iLA0KICAgICAgICAgICAgICAgICAgICAgICAiPGI+VG90YWwgWWVhcmx5IENvbXBlbnNhdGlvbjo8L2I+ICQiLCB0YykpICU+JQ0KICAgICAgICBsYXlvdXQoDQogICAgICAgICAgbWFwYm94ID0gbGlzdCgNCiAgICAgICAgICAgIHN0eWxlID0gJ29wZW4tc3RyZWV0LW1hcCcsDQogICAgICAgICAgICBjZW50ZXIgPSBsaXN0KGxvbiA9IC05NywgbGF0ID0gMzgpLA0KICAgICAgICAgICAgem9vbSA9IDIuNSkpIA0KICAgICAgICAgIH0pDQp9DQoNCnNoaW55QXBwKHVpLCBzZXJ2ZXIpDQpgYGANCg0KTG9va2luZyBhdCBkaWZmZXJlbnQgcm9sZXMgaW4gY29tcGFuaWVzIGJhc2VkIG9uIHJvbGUNCg0KYGBge3J9DQpjb24gPC0gZmFjdG9yKHVuaXF1ZShsZXZlbHNfZGZbYygidGl0bGUiKV0pJHRpdGxlKQ0KY29uDQpgYGANCg0KLSAgIEZpcnN0IGdyb3VwIGJ5IGxvY2F0aW9uICsgY29tcGFueQ0KDQotICAgVGhlbiBzcGxpdCBieSB5b2UNCg0KLSAgIElmIHRoZXJlJ3MgYXQgbGVhc3QgYSBtYWxlICYgZmVtYWxlIHBlciBsb2NhdGlvbiArIGNvbXBhbnksIGluY2x1ZGUgaW4gZGF0YS4gRWxzZSBleGNsdWRlDQoNCiAgICBMZXQncyBiZWdpbiB3aXRoIGFuIGV4YW1wbGUgdG8gc2VlDQoNCmBgYHtyfQ0KbmV3X2VudHJ5IDwtIG5ld19lbnRyeSAlPiUgDQogICAgICAgICAgICAgICAgZHJvcF9uYShiYXNlc2FsYXJ5KSAgJT4lDQogICAgICAgICAgICAgICAgZHJvcF9uYSh0aXRsZSkgJT4lDQogICAgICAgICAgICAgICAgZHJvcF9uYShzdG9ja2dyYW50dmFsdWUpICU+JQ0KICAgICAgICAgICAgICAgIGRyb3BfbmEoYm9udXMpDQoNCm5ld19lbnRyeV90YyA8LSBhZ2dyZWdhdGUobGlzdCh0YyA9IG5ld19lbnRyeSR0b3RhbHllYXJseWNvbXBlbnNhdGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlc2FsYXJ5ID0gbmV3X2VudHJ5JGJhc2VzYWxhcnksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvY2tncmFudHZhbHVlID0gbmV3X2VudHJ5JHN0b2NrZ3JhbnR2YWx1ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib251cyA9IG5ld19lbnRyeSRib251cyksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBieT1saXN0KCB0aXRsZT1uZXdfZW50cnkkdGl0bGUsIHN0YXRlPW5ld19lbnRyeSRzdGF0ZSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBGVU49bWVhbiwgbmEuYWN0aW9uID0gbmEub21pdCkNCiNuYW1lcyhuZXdfZW50cnlfdGMpWzJdIDwtICJzdGF0ZSINCiNuYW1lcyhuZXdfZW50cnlfdGMpWzNdIDwtICJ0YyINCiNuYW1lcyhuZXdfZW50cnlfdGMpWzRdIDwtICJiYXNlc2FsYXJ5Ig0KI25hbWVzKG5ld19lbnRyeV90YylbNV0gPC0gInN0b2NrZ3JhbnR2YWx1ZSINCiNuYW1lcyhuZXdfZW50cnlfdGMpWzZdIDwtICJib251cyINCg0KbmV3X2VudHJ5X3RjDQpgYGANCg0KYGBge3J9DQpsb2NhdGlvbl9kZiA8LSBuZXdfZW50cnkgJT4lIA0KICBkaXN0aW5jdChzdGF0ZSwgLmtlZXBfYWxsID0gVFJVRSkgJT4lDQogIHNlbGVjdChzdGF0ZSwgbGF0LCBsb25nKSAlPiUgbmEub21pdCgpDQojIGxvY2F0aW9uX2RmIDwtIG5hLm9taXQobG9jYXRpb25fZGYpDQpsb2NhdGlvbl9kZg0KYGBgDQoNCmBgYHtyfQ0KbmV3X2VudHJ5X3RjIDwtIG5ld19lbnRyeV90YyAlPiUNCiAgbGVmdF9qb2luKGxvY2F0aW9uX2RmKQ0KbmV3X2VudHJ5X3RjDQpgYGANCg0KYGBge3J9DQpuZXdfZW50cnlfdGMgJT4lIA0KICBmaWx0ZXIoc3RhdGUgPT0gIkFSIikgJT4lDQogIGdncGxvdChhZXMoeCA9IHRpdGxlLCB5ID0gdGMsIGZpbGwgPSB0aXRsZSkpICsNCiAgZ2VvbV90ZXh0KGFlcyh5ID0gdGMsIGxhYmVsID0gdGMsIGhqdXN0PTApLCANCiAgICAgICAgICAgICAgICAgIHNpemUgPSAzKSArDQogICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSsNCiAgICAgICAgY29vcmRfZmxpcCgpKw0KICAgICAgICBsYWJzKHggPSAiIiwgeSA9ICIiKSsNCiAgICAgICAgZ2d0aXRsZShwYXN0ZSgiSGVsbG8iKSkrDQogICAgICAgIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQo=